// Package base_context：理解Go中的上下文,重要的是理解上下文和协程之间的关系，以及如何各个协程之间的关系.
// @author: zhenxinma.
// @create: 2021-09-15 19:47:26
package main

import (
	"context"
	"fmt"
	"time"
)

/**
1. context.WithCancel 创建可以取消的Context对象，即可以主动通知子协程进行退出，其实现效果和select +  chan相同.
2. context.Backgroud() 创建根Context对象，通常在main函数、初始化代码块中创建，作为顶层的Context对象.
   在子协程中使用select调用<-ctx.Done()判断是否需要进行退出.
   主协程中，调用cancel()函数通知子协程进行退出.
3. context.WithValue() 创建了一个基于ctx的子Context,并且携带了值options,在子协程中，使用ctx.Value("key")获取传递的值，并且进行修改.
4. WithTimeout()的使用与WithCancel()类似，多了一个参数，用于设置超时时间.
5. WithDeadline用于设置截止时间.
*/

// TODO: 上下文暂时学习到这里.

func main() {

	// context.Background() 返回一个empCtx的Context.
	ctx, cancel := context.WithCancel(context.Background())
	go Task(ctx)
	time.Sleep(3 * time.Second)
	// main 等待三秒之后进行关闭.
	cancel()
}

func Task(ctx context.Context) {
	select {
	case <-ctx.Done():
		fmt.Println("end")
	default:
		fmt.Println("default")
	}
	fmt.Println("Task end")
}
